package org.shs.common.config;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.struts.util.MessageResources;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

/**
 * 
 * <br/>
 * <br/><b>Created:</b>&nbsp;&nbsp; Nov 5, 2008 4:34:18 PM
 *
 * @author anirvan
 *
 */
public class SystemInitializer extends HttpServlet
{
   
   /**
    * Default serialization ID
    */
   private static final long serialVersionUID = 1L;

   /**
    * The place holder for the log directory in log4j config file.
    */
   private static final String LOG_FILE_LOCATION = "LOG_FILE_LOCATION";
   
   /**
    * SqlMapClient instances are thread safe, so you only need one. In this
    * case, we'll use a static singleton. So sue me. ;-)
    */
   public static SqlMapClient sqlHandler;

   /**
    * The logger used
    */
   private static Logger logger = null;

   /**
    * Message resources used to configure the UI and system behaviour.
    */
   public static MessageResources app_msgs = null;

   /**
    * @see HttpServlet#HttpServlet()
    */
   public SystemInitializer()
   {
      super();
   }

   /**
    * @see Servlet#init(ServletConfig)
    */
   public void init(ServletConfig srvltConfig) throws ServletException
   {
      String path = null;
      File logConfFile = null;
      Properties logProps = null;

      super.init();

      app_msgs = MessageResources.getMessageResources(
                           srvltConfig.getInitParameter("config-file"));

      path = srvltConfig.getServletContext().getRealPath("");
      logConfFile = new File(path, srvltConfig.getInitParameter("log-config"));
      logProps = new Properties();
      try
      {
         FileInputStream fis = new FileInputStream(logConfFile);
         logProps.load(fis);
         fis.close();
      }
      catch (Exception e)
      {
         String errMsg = "Could not read log4j config file: " + logConfFile;
         System.err.println(errMsg);
         e.printStackTrace(System.err);
         throw new ServletException(errMsg, e);
      }
      logProps.setProperty(LOG_FILE_LOCATION, 
                              app_msgs.getMessage("app.outputLog.location"));
      PropertyConfigurator.configure(logProps);
      logger = Logger.getLogger(this.getClass());
      logger.info("===> Initialized Logging");

      // Initialize the SQL map handler
      try
      {
         Reader reader = Resources.getResourceAsReader(
                              srvltConfig.getInitParameter("sqlMap-config"));
         sqlHandler = SqlMapClientBuilder.buildSqlMapClient(reader);
         reader.close();
         logger.info("===> SQL Configuration is good to go.");
      }
      catch (IOException e)
      {
         // Fail fast.
         logger.fatal("Problem in accessing the SQL Configuration.", e);
      }
      catch (Throwable t)
      {
         logger.fatal(
          "===> Something bad happened while setting up the SQL Configuration.", t);
      }
      
   }

   /**
    * @see Servlet#destroy()
    */
   public void destroy()
   {
      super.destroy();
      // Terminate all SQL loose ends
      sqlHandler.flushDataCache();
      try
      {
         if (sqlHandler.getCurrentConnection() != null)
         {
            sqlHandler.getCurrentConnection().close();
         }
      }
      catch (Exception e) 
      {
         logger.error("Could not close current connection.", e);
      }
      sqlHandler = null;
      
      logger.info("DB connection closed successfully.");
   }
}